<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <script>
    // function debounce(func, delay) {
    //   let timerId = null;

    //   return function (...args) {
    //     const context = this; // 保存正确的上下文
    //     timerId && clearTimeout(timerId);

    //     timerId = setTimeout(() => {
    //       func.apply(context, args);
    //     }, delay);
    //   };
    // }

     function debounce(func, wait) {
       let timerId = null;
       let lastArgs = null;
       let lastContext = null
       const debounced = function (...args) {
         lastArgs = args;
         lastContext = this;
         timerId && clearTimeout(timerId)
         timerId = setTimeout(() => {
           func.apply(lastContext, args);
           timerId = null;
           lastArgs = null;
           lastContext = null;
         }, wait);
       };
       // 加上取消功能
       debounced.cancel = function () {
         clearTimeout(timerId);
         timerId = null;
         lastArgs = null;
         lastContext = null;
       }
       //   立即执行清除的定时器
       debounced.flush = function () {
         if (timerId) {
           func.apply(lastContext, lastArgs)
           clearTimeout(timerId);
           timerId = null;
           lastArgs = null;
           lastContext = null;
         }
       };
    Object.defineProperty(debounced, 'pending', {
        get: () => timeoutId !== null,
      });

       return debounced;
     }
    // 提高健状性
    function debounce(func, delay) {
      let timeoutId = null;
      let context = null;
      let debounceArgs = null;

      const debounced = function (...args) {
        context = this;
        debounceArgs = args;
        timeoutId && clearTimeout(timeoutId);

        setTimeout(() => {
          try {
            func.apply(context, debounceArgs);
          } finally {
            timeoutId = null;
            context = null;
            debounceArgs = null;
          }
        }, delay);
      };

      debounced.cancel = () => {
        if (timeoutId) {
          clearTimeout(timeoutId);
          timeoutId = null;
          context = null;
          debounceArgs = null;
        }
      };

      debounced.flush = () => {
        if (timeoutId) {
          try {
            func.apply(context, debounceArgs);
          } finally {
            debounced.cancel();
          }
        }
      };
      //   添加状态管理 , 这里就是加了个pending的属性，然后使用的时候可以看下有没有定时器在等待， 如果为true表示有搜索请求在等待中
      Object.defineProperty(debounced, 'pending', {
        get: () => timeoutId !== null,
      });

      return debounced;
    }

    // 创建一个防抖函数
    const debouncedSearch = debounce((query) => {
      console.log('搜索:', query);
    }, 300);

    // 模拟用户输入
    debouncedSearch('apple');
    debouncedSearch('apple1');
    debouncedSearch('apple2');
    debouncedSearch('apple3');

    // 检查状态
    console.log(debouncedSearch.pending); // true，表示有定时器在等待

    // 300ms 后，定时器执行，状态变为 false
    setTimeout(() => {
      console.log(debouncedSearch.pending); // false
    }, 400);

    // 假设这是一个搜索输入框的处理函数
    function handleSearch(query) {
      const debounced = debounce(() => {
        // 执行搜索逻辑
        console.log('执行搜索:', query);
      }, 500);

      // 调用防抖搜索
      debounced();

      // 可以检查状态并决定是否取消
      if (debounced.pending) {
        console.log('搜索请求正在等待中');

        // 如果需要，可以取消
        // debounced.cancel();
      }
    }
  </script>
  <body></body>
</html>
